﻿using System;
using System.Data.SqlClient;
using System.IO;

namespace SQLBackup
{
    internal class DbBackUp : IDbBackUp
    {
        public string ConnectionString { get; set; }
        public string DbBackUpPath { get; set; }
        public string DbName { get; set; }
        public string  DifferentialInfo { get; set; }
        public bool IsDifferential { get; set; }

        private const string KConfigExtension = ".bak";

        public  DbBackUp()
        {       
            /*ConnectionString = Config.DBConnectionString;
            DbBackUpPath = Config.DBBackUpFilePath;
            DbName = Config.DBName;

            DifferentialInfo = (IsDifferential) ? "WITH  DIFFERENTIAL , NOFORMAT, NOINIT" : "WITH FORMAT";*/
            
        }

        public DbBackUp(string configFilePath)
        {
            try
            {
                if (!File.Exists(configFilePath))
                {
                    string msg = string.Format("This service cannot start because no configuration data found at {0}", configFilePath);
                    throw new Exception(msg);
                }

                var configInfo = Utility.ReadSettingsFromXml(configFilePath);

                ConnectionString = Config.DBConnectionString; //Common.SetConnectionString("DBConnection", true);

                DbBackUpPath = configInfo.DbBackUpFilePath;
                DbName = configInfo.DbName;
                Config.ActivityLog = configInfo.ActivityLogPath;
                DifferentialInfo = (configInfo.BackupType.Equals(Constant.K_DIFFERENTIAL_BACKUP_TYPE))
                                                    ? " WITH  DIFFERENTIAL , NOFORMAT, NOINIT" : " WITH FORMAT";
            }
            catch (Exception excpt)
            {

                Utility.LogErrorToFile(excpt + " at Date Time " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt"));
            }
        }

        
        /// <summary>
        /// This method will call the DB back and will and will generate the bach up file
        /// </summary>
        /// <returns></returns>
        public bool RunDbBackUp()
        {
            var dbExtenstiion = Environment.TickCount;
            if (!string.IsNullOrEmpty(ConnectionString) && 
                !string.IsNullOrEmpty(DbBackUpPath) && 
                !string.IsNullOrEmpty(DbName))
            {
                var sqlQuery = @"USE " + DbName + ";" +
                                  "BACKUP DATABASE " + DbName + " TO DISK = '" + DbBackUpPath +"\\"+
                                  DbName + Convert.ToString(dbExtenstiion) + KConfigExtension + "'" + DifferentialInfo + ";";

                Utility.LogMessageToFile(sqlQuery);

                if (ExecuteNonQuerySqlStatement(sqlQuery, ConnectionString))
                {
                    Utility.LogMessageToFile("Backup file path " + DbBackUpPath +
                                     DbName + KConfigExtension +" for DataBase " + DbName + " Created at " +
                                     DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt"));
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Will execute a query to generate the Db back up
        /// </summary>
        /// <param name="aRandomSql">sql query</param>
        /// <param name="conn">connection string</param>
        /// <returns></returns>
        private  bool ExecuteNonQuerySqlStatement(string aRandomSql, string conn)
        {
            var isBackUpTaken = false;
            try
            {
                using (var storeConnection = new SqlConnection(conn))
                {
                    storeConnection.InfoMessage += ConnInfoMessage;
                    using (var command = storeConnection.CreateCommand())
                    {
                        command.CommandText = aRandomSql;
                        command.CommandTimeout = 0;
                        storeConnection.Open();

                        command.ExecuteNonQuery();

                        storeConnection.Close();
                        isBackUpTaken = true;
                    }
                }
            }
            catch (SqlException sqlexpt)
            {
                Utility.LogErrorToFile(sqlexpt + " at Date Time " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt"));
            }
            return isBackUpTaken;
        }

        /// <summary>
        /// To log the Db backup activity of the application 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void ConnInfoMessage(object sender, SqlInfoMessageEventArgs e)
        {
            var myMsg = e.Message;
            Utility.LogMessageToFile(myMsg);
        }
    }
}
